/**
 * 部署的通用函数
 */

const child_process = require('child_process');
const util = require('util');
const execFile = util.promisify(child_process.execFile);

const exec = child_process.exec;
// 引入shell.js等依赖
const shell = require('shelljs');
const { echo } = shell;//打印
const { exit } = shell;//退出命令
const inquirer = require('inquirer');//交互
const chalk = require('chalk');//颜色
const ora = require('ora');//loading
const commander = require("commander");//判断
const { Console } = require('console');
const program = new commander.Command();
const log = console.log;
program.version('0.0.1');

//定义pya-deploy项目的目录
const pay_deploy_dir = shell.pwd();
const buffer_size = 20 * 1024 * 1024;//执行子进程，stdout的最大缓存大小

/**
 * 获取git地址中的项目名称
 * @param {*} git_address 
 * @returns 
 */
function gitProjectName(git_address) {
    let regExp = new RegExp(/(?<=\/)[^\/]+(?=\.git)/);
    let project_name = regExp.exec(git_address)[0];//项目名称
    return project_name
}

/**
 * 拉取源代码
 * @param {*} parent_dir 存放源代码的父级目录
 * @param {*} git_address git地址
 * @returns 0是执行成功，其它值是执行失败
 */
async function git_clone(parent_dir, git_address) {
    let git_buffer = 10 * buffer_size;
    //设置 sh 命令执行的参数
    let cmd = "sh " + pay_deploy_dir + "/shell/git_clone.sh";

    //设置环境变量
    let environment = { 'parent_dir': parent_dir, 'git_address': git_address, ...process.env };
    let options = { async: false, silent: false, cwd: parent_dir, env: environment, shell: '/bin/bash', maxBuffer: git_buffer };

    //阻塞的方式
    const result = shell.exec(cmd, options);
    //输出执行结果
    console.log(result.stdout);
    console.log(result.stderr);
    return result.code;//0是执行成功，其它值是执行失败
}



/** 生成jar包
 * @param src_dir 项目源代码所在目录
 */
async function bulid_jar2(src_dir) {
    shell.cd(src_dir);
    if (!shell.test('-f', "pom.xml")) {
        echo('未找到pom.xml文件');
        exit(1);
    }

    if (shell.test('-e', src_dir + "/local-maven-repo")) {//如果旧代码存在，则删除
        shell.cp('-rf', src_dir + "/local-maven-repo/*", process.env.HOME + '/.m2');
    }
    //设置 sh 命令执行的参数
    let args = [pay_deploy_dir + "/shell/build_jar.sh"];

    //设置环境变量
    let environment = { 'src_dir': src_dir, ...process.env };
    let options = { env: environment, shell: '/bin/bash', maxBuffer: buffer_size };

    // 异步的方式
    // child_process.execFile('sh', args, options, (error, stdout, stderr) => {
    //     if (error) {
    //         console.error(error);
    //     }
    //     console.log(stdout);
    // });

    //阻塞的方式
    const { stdout } = await execFile('sh', args, options);
    console.log(stdout);//输出执行结果
}

/** 生成jar包
 * @param src_dir 项目源代码所在目录
 * @returns 0代表成功
 */
async function bulid_jar(src_dir) {
    shell.cd(src_dir);
    if (!shell.test('-f', "pom.xml")) {
        echo('未找到pom.xml文件');
        exit(1);
    }

    if (shell.test('-e', src_dir + "/local-maven-repo")) {//如果旧代码存在，则删除
        shell.cp('-rf', src_dir + "/local-maven-repo/*", process.env.HOME + '/.m2');
    }
    //设置 sh 命令执行的参数
    let cmd = "sh " + pay_deploy_dir + "/shell/build_jar.sh"

    //设置环境变量
    let environment = { 'src_dir': src_dir, ...process.env };
    let options = { env: environment, shell: '/bin/bash', maxBuffer: buffer_size };

    //阻塞的方式
    const result = shell.exec(cmd, options);
    const { stdout, stderr, code } = result;
    console.log(stdout);//输出执行结果
    console.log(stderr);
    return code;
}

/** 生成jar包
 * @param src_dir 项目源代码所在目录
 * @param npm_commod npm命令
 * @param node_version node的版本号
 * @returns 0代表成功
 */
async function bulid_npm(src_dir, npm_commod, node_version) {
    shell.cd(src_dir);
    if (!shell.test('-f', "package.json")) {
        echo('未找到package.json文件');
        exit(1);
    }

    //设置 sh 命令执行的参数
    let cmd = "sh " + pay_deploy_dir + "/shell/build_npm.sh"
    if (node_version && node_version == '14') {
        cmd = "sh " + pay_deploy_dir + "/shell/build_npm14.sh"
    }

    //设置环境变量
    let environment = { 'src_dir': src_dir, 'npm_commod': npm_commod, ...process.env };
    let options = { env: environment, shell: '/bin/bash', maxBuffer: buffer_size };

    //阻塞的方式
    const result = shell.exec(cmd, options);
    const { stdout, stderr, code } = result;
    console.log(stdout);//输出执行结果
    console.log(stderr);
    return code;
}


/**
 * 解析pom.xml，得到jar包名称
 * @param project_dir 项目目录
 * @returns jar包名称
 */
function pom_jar_name(project_dir) {
    const command = "sh " + pay_deploy_dir + "/shell/pom_version.sh";
    let child = shell.exec(command, { silent: true, encoding: 'utf8', cwd: project_dir, shell: '/bin/bash' });//
    let jarName = child.stdout.trim().replace("\n", "-") + ".jar";
    console.log(jarName);
    return jarName;
}


async function getVersion() {
    const { stdout } = await execFile('node', ['--version']);
    console.log(stdout);
}

//测试：打印环境变量
async function exportEnv() {
    let args = ["./shell/export.sh"];
    let environment = { 'src_dir': src_dir, ...process.env };
    const { stdout } = await execFile('sh', args, { env: environment, shell: '/bin/bash' });

    execFile(cmd, { async: true }, function (code, stdout, stderr) {
        console.log('Exit code:', code);
        console.log('Program output:', stdout);
        console.log('Program stderr:', stderr);
        if (code !== 0) {
            echo('克隆失败，请检查克隆地址是否存在');
            exit(1);
        } else {
            // 克隆过程
            stdout.on('data', data => console.log('stdout: ', data))
        }

    });
    console.log(stdout);
}
// exportEnv();

function getGitAddress() {
    // 输入仓库git
    inquirer.prompt({
        type: 'input',
        name: 'git',
        message: '输入git地址',
        validate: function (input) {
            // 加载动画
            let spinner = ora('正在校验');
            spinner.start();
            var done = this.async();
            // Do async stuff
            setTimeout(function () {
                spinner.stop();
                if (input.indexOf('.git') > -1) {
                    // 成功
                    done(null, true);
                } else {
                    done('请输入合法的地址');
                    return;
                }
            }, 1000);
        }
    }).then((res) => {
        echo('克隆仓库', 'git clone ' + res.git);
        getClone(res.git)
    });

}


// 执行命令
function Runing(cmd) {
    exec(cmd, { async: true }, function (code, stdout, stderr) {
        console.log('Exit code:', code);
        console.log('Program output:', stdout);
        console.log('Program stderr:', stderr);
        if (code !== 0) {
            echo('克隆失败，请检查克隆地址是否存在');
            exit(1);
        } else {
            // 克隆过程
            stdout.on('data', data => console.log('stdout: ', data))
        }

    });
}


// 执行命令
function execLog(cmd) {
    exec(cmd, { async: true }, function (code, stdout, stderr) {
        console.log('Exit code:', code);
        console.log('Program output:', stdout);
        console.log('Program stderr:', stderr);
        if (code !== 0) {
            echo('克隆失败，请检查克隆地址是否存在');
            exit(1);
        } else {
            // 克隆过程
            stdout.on('data', data => console.log('stdout: ', data))
        }

    });
}

/**
 * 
 * @param file shell文件
 * @param args 数组
 */
function execFileLog(file) {
    child_process.execFile(file, function (error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });
}

/**
 * 删除目录
 * @param {*} dir 
 */
function deleteDir(dir) {
    if (shell.test('-e', dir))
        shell.rm('-rf', dir);
}

module.exports = {
    gitProjectName,
    git_clone,
    bulid_jar,
    bulid_npm,
    pom_jar_name,
    deleteDir
}


//测试 pom_jar_name()
// let project_dir='/deploy/src/pay-admin';
// let jar = pom_jar_name(project_dir);
